package Client_Module;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
//import java.util.Calendar;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.locks.LockSupport;

public class Client_Worker {
    public Socket socket_client;
    public boolean force_stop = false;
    private Thread cworker_read_thread;
    private Thread cworker_send_thread;
    private Thread cdisplay_data_thread;
    private int[] Window_status = new int[6];
    private long[] Pressure_Test_Window_time = new long[6];
    // private Calendar Pressure_Test_Time;// 初始化日期对象 用于压力测试 自动完成时间
    private boolean pressure_test_mode = false;
    private Scanner input = new Scanner(System.in);

    public Client_Worker(String ip, int port) {
        try {
            socket_client = new Socket(ip, port);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.print("请输入运行模式(1.手动 2.压力测试 3.退出系统):");
        switch (input.nextInt()) {// 输入运行模式
            case 2:
                pressure_test_mode = true;
                break;
            case 3:
                input.close();
                return;
        }
        System.out.print("开始运行");
    }

    public String format_data(String text, int lx) { // 类型(info/request/response)#窗口(1-5)$信息
        if (lx == 0) {
            if (text.indexOf("#") != -1) {
                return "OK";
            }
        }
        if (lx == 1) {
            return text.substring(0, text.indexOf("#"));
        }
        if (lx == 2) {
            return text.substring(text.indexOf("#") + 1, text.indexOf("$"));
        }
        if (lx == 3) {
            return text.substring(text.indexOf("$") + 1, text.length());
        }
        return "";
    }

    private void Change_Windows_Status(int wnum, int status) {// 更改窗口状态
        Window_status[wnum - 1] = status;
        LockSupport.unpark(cdisplay_data_thread);
    }

    private int Get_Windows_Status(int wnum) {// 获取窗口状态
        return Window_status[wnum - 1];
    }

    private String Windows_Status_Convert(int status) {// 窗口状态转文字
        String temp = "";
        switch (status) {// 输入状态
            case 1:
                temp = "等待中";
                break;
            case 2:
                temp = "工作中";
                break;
            // case 3:
            // windows[wnum - 1][1] = "done";
            // break;
            case 0:
                temp = "空闲中";
                break;
            default:
                temp = "无效中";
                break;
        }
        return temp;
    }

    private void Display_Work_Windows_Status() {
        cdisplay_data_thread = new Thread(new Runnable() {
            @Override
            public void run() {

                while (!force_stop) {
                    LockSupport.park();
                    String temp = "";
                    for (int i = 1; i <= 5; i++) {
                        temp = temp + "窗口" + i + ":" + Windows_Status_Convert(Window_status[i - 1]) + " ";
                        if (pressure_test_mode == true) {
                            temp = temp + "窗口" + i + ":" + Pressure_Test_Window_time[i - 1] + " ";
                        }
                    }
                    try {
                        clear_control_board();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("各个窗口状态：");
                    System.out.println(temp);
                    System.out.print("请输入欲要结束的窗口号:");
                    // try {
                    // Thread.sleep(10);
                    // }// catch (InterruptedException e) {
                    // e.printStackTrace();
                    // }//
                }
            }

        });
        cdisplay_data_thread.start();
    }

    private void Worker_Windows_Main(int wnum, int status) {
        Change_Windows_Status(wnum, status);
        // Display_Work_Windows_Status();
    }

    public void Read() {
        cworker_read_thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InputStream indata = socket_client.getInputStream();
                    DataInputStream indatastream = new DataInputStream(indata);
                    // output("connect");
                    String temp;
                    int temp_status, temp_win;
                    // temp = indatastream.readUTF();
                    Display_Work_Windows_Status();
                    while (true) {
                        temp = indatastream.readUTF();
                        checkDown(temp);
                        temp_win = Integer.valueOf(format_data(temp, 2));
                        temp_status = Integer.valueOf(format_data(temp, 3));
                        // System.out.println(temp);// 测试用途
                        Worker_Windows_Main(temp_win, temp_status);
                        pressure_test(800, temp_status, temp_win); // 用于压力测试 压力测试完毕 要注释掉
                        if (pressure_test_mode == false) {
                            Thread.sleep(2000); // 压力测试需要去除
                        }

                        // }
                        if (force_stop == true) {
                            break;
                        }
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        cworker_read_thread.start();

    }

    public void Send() {
        cworker_send_thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int temp_input;
                    while (true) {
                        temp_input = input.nextInt();
                        output("response#" + temp_input + "$done");
                        if (force_stop == true) {
                            break;
                        }
                    }
                    input.close();

                } finally {
                }
            }
        });
        cworker_send_thread.start();
    }

    public synchronized void output(String text) {
        try {
            OutputStream outdata = socket_client.getOutputStream();
            DataOutputStream outdatastream = new DataOutputStream(outdata);
            outdatastream.writeUTF(text);
            // System.out.println(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean pressure_test_pddx(Long l1, Long l2) {
        if (l1.longValue() > l2.longValue()) {
            return true;
        }
        return false;
    }

    private void pressure_test(int time, int i, int wi) throws InterruptedException { // 压力测试 参数：延时/状态/窗口
        if (pressure_test_mode == false) {
            return;
        }
        String temp = "";
        // for (int i = 1; i <= 5; i++) {
        if (i == 2) {
            Pressure_Test_Window_time[wi - 1] = pressure_test_getRanTime(); // 生成随机时间
            // System.out.println(temp);
        }

        for (int ii = 1; ii <= 5; ii++) {
            if (pressure_test_pddx(pressure_test_nowtime(), Pressure_Test_Window_time[ii - 1]) == true
                    && Window_status[ii - 1] == 2) {
                Pressure_Test_Window_time[ii - 1] = 0;
                temp = "response#" + ii + "$done";
                output(temp);
                Change_Windows_Status(ii, 0);

            }
        }
        Thread.sleep(1000);
        // }

    }

    private long pressure_test_nowtime() {
        long time = System.currentTimeMillis();
        return time;
    }

    private long pressure_test_getRanTime() {
        long time;
        Random RD = new Random();
        int RandomTime = Integer.valueOf((int) (RD.nextDouble() * 10));
        time = System.currentTimeMillis() + (RandomTime * 1000);
        return time;
    }

    private void clear_control_board() throws IOException {
        System.out.print("\033[H\033[2J");
        System.out.flush();
    }

    private void checkDown(String temp) {
        if (temp.equals("ShutdownNow")) {
            System.exit(0);
        }
    }
}
